package com.relytosoft.mizar.media.host.emqx;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.relytosoft.dubhe.common.core.utils.BeanCopyUtils;
import com.relytosoft.dubhe.common.redis.utils.RedisUtil;
import com.relytosoft.mizar.media.analyze.api.entity.structure.AyStructureDisposition;
import com.relytosoft.mizar.media.analyze.api.entity.structure.AyStructureTask;
import com.relytosoft.mizar.media.analyze.api.entity.structure.AyStructureTaskSon;
import com.relytosoft.mizar.media.analyze.services.service.structure.AyStructureDispositionService;
import com.relytosoft.mizar.media.analyze.services.service.structure.AyStructureTaskService;
import com.relytosoft.mizar.media.analyze.services.service.structure.AyStructureTaskSonService;
import com.relytosoft.mizar.media.camera.services.service.CameraBaseService;
import com.relytosoft.mizar.media.common.constant.AlarmTypeConstants;
import com.relytosoft.mizar.media.common.constant.AyCacheConstants;
import com.relytosoft.mizar.media.common.constant.MediaMqConstants;
import com.relytosoft.mizar.media.common.entity.pojo.dto.AyDispositionPlanDto;
import com.relytosoft.mizar.media.common.enums.ControlStatusEnum;
import com.relytosoft.mizar.media.common.enums.DeleteStatusEnum;
import com.relytosoft.mizar.media.common.enums.StruDispositionTypeEnum;
import com.relytosoft.mizar.media.common.enums.TaskStatusEnum;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * StruDataMqttMessageListener
 *
 * @Author SunLi
 * @Date: 2022/5/31 14:33
 * @Version 1.0
 */
@Component
public class StruDataMqttMessageListener implements com.relytosoft.mizar.media.common.emqx.listener.StruDataMqttMessageListener {

    private static final Logger log = LoggerFactory.getLogger(FaceMqttMessageListener.class);

    @Resource
    private AyStructureTaskSonService taskSonService;
    @Resource
    private AyStructureTaskService taskService;
    @Resource
    private AyStructureDispositionService dispositionService;
    @Resource
    private CameraBaseService cameraBaseService;

    @Override
    public void messageArrived(String topic, MqttMessage message) throws Exception {
        if (topic.equals(MediaMqConstants.STRUCTURE_DATA_TOPIC)) {
            boolean isConsume = false;
            String mqttMsg = new String(message.getPayload(), StandardCharsets.UTF_8);
            try {
                JSONObject jsonObject = JSON.parseObject(mqttMsg);
                String opType = jsonObject.getString("OpType");
                String data = jsonObject.getString("Data");
                switch (opType) {
                    //更新实时分析任务第三方ID
                    case "updateTaskId":
                        isConsume = updateTaskId(data);
                        break;
                    //更新实时分析任务状态
                    case "updateTaskStatus":
                        isConsume = updateTaskStatus(data);
                        break;
                    //更新布控任务第三方ID
                    case "updateDispositionId":
                        isConsume = updateDispositionId(data);
                        break;
                    //任务创建失败时更新状态
                    case "taskUnusual":
                        isConsume=taskUnusual(data);
                        break;
                    case "dispositionUnusual":
                        isConsume=dispositionUnusual(data);
                        break;
                    default:
                        break;
                }
                log.info("线程名称：【" + Thread.currentThread().getName() + "】" + "接收的主题：" + topic + ",接收的操作类型：" + opType + "，执行结果：" + isConsume);
            } catch (Exception e) {
                log.info("线程名称：【" + Thread.currentThread().getName() + "】" + "接收的主题：" + topic + ",处理发生错误：" + e.getMessage());
            }
        }
    }

    /**
     * 更新子任务的taskId
     *
     * @param data 任务信息
     * @return 消费结果
     */
    private boolean updateTaskId(String data) {
        JSONObject jsonObject = JSON.parseObject(data);
        Integer sonId = jsonObject.getInteger("id");
        String taskId = jsonObject.getString("taskId");

        return taskSonService.getBaseMapper().update(null, new LambdaUpdateWrapper<AyStructureTaskSon>().set(AyStructureTaskSon::getTaskId, taskId).set(AyStructureTaskSon::getUpdatedBy, "SYSTEM")
                .eq(AyStructureTaskSon::getId, sonId)) == 1;
    }

    /**
     * 更新子任务的状态
     *
     * @param data 任务信息
     * @return 消费结果
     */
    private boolean updateTaskStatus(String data) {
        JSONObject jsonObject = JSON.parseObject(data);
        Integer code = jsonObject.getInteger("code");
        String taskId = jsonObject.getString("taskId");
        String msg = jsonObject.getString("msg");
        AyStructureTaskSon taskSon = taskSonService.getByTaskId(taskId);
        if (taskSon != null) {
            if (code != 0) {
                //更新子任务为异常
                LambdaUpdateWrapper<AyStructureTaskSon> wrapper = new LambdaUpdateWrapper<AyStructureTaskSon>().set(AyStructureTaskSon::getStatus, TaskStatusEnum.UNUSUAL.getValue()).set(AyStructureTaskSon::getUpdatedBy, "SYSTEM").set(AyStructureTaskSon::getErrorReason, msg)
                        .eq(AyStructureTaskSon::getId, taskSon.getId()).eq(AyStructureTaskSon::getStatus, TaskStatusEnum.CREATED.getValue()).eq(AyStructureTaskSon::getIsDeleted, DeleteStatusEnum.NOT_DELETED.getValue());

                boolean updateSonRes = taskSonService.update(null, wrapper);
                if (updateSonRes) {
                    //更新主任务为异常
                    LambdaUpdateWrapper<AyStructureTask> wrapper1 = Wrappers.lambdaUpdate();
                    wrapper1.eq(AyStructureTask::getId, taskSon.getStructureTaskId());
                    List<Integer> status=new ArrayList<>(Arrays.asList(TaskStatusEnum.CREATED.getValue(),TaskStatusEnum.RUNING.getValue()));
                    wrapper1.in(AyStructureTask::getStatus, status);
                    wrapper1.eq(AyStructureTask::getIsDeleted, DeleteStatusEnum.NOT_DELETED.getValue());

                    wrapper1.set(AyStructureTask::getStatus, TaskStatusEnum.UNUSUAL.getValue());
                    wrapper1.set(AyStructureTask::getErrorReason, msg);
                    wrapper1.set(AyStructureTask::getUpdatedBy, "SYSTEM");
                    taskService.getBaseMapper().update(null, wrapper1);
                }
                return updateSonRes;
            } else {
                //更新子任务为运行中
                LambdaUpdateWrapper<AyStructureTaskSon> wrapper = Wrappers.lambdaUpdate();
                wrapper.eq(AyStructureTaskSon::getId, taskSon.getId());
                wrapper.eq(AyStructureTaskSon::getStatus, TaskStatusEnum.CREATED.getValue());
                wrapper.eq(AyStructureTaskSon::getIsDeleted, DeleteStatusEnum.NOT_DELETED.getValue());


                wrapper.set(AyStructureTaskSon::getStatus, TaskStatusEnum.RUNING.getValue());
                wrapper.set(AyStructureTaskSon::getUpdatedBy, "SYSTEM");


                boolean updateSonRes = taskSonService.getBaseMapper().update(null, wrapper) == 1;
                if (updateSonRes) {
                    //更新主任务为已成功启动过
                    LambdaUpdateWrapper<AyStructureTask> wrapper1 = Wrappers.lambdaUpdate();
                    wrapper1.eq(AyStructureTask::getId, taskSon.getStructureTaskId());
                    wrapper1.eq(AyStructureTask::getIsDeleted, DeleteStatusEnum.NOT_DELETED.getValue());

                    wrapper1.set(AyStructureTask::getIsStartUp, 1);
                    taskService.getBaseMapper().update(null, wrapper1);
                    //更新主任务为运行中
                    taskService.taskStatusHandle(taskSon.getStructureTaskId(), TaskStatusEnum.RUNING.getValue());
                }
                return updateSonRes;
            }
        } else {
            return false;
        }
    }

    /**
     * 更新布控任务的DispositionId
     *
     * @param data 任务信息
     * @return 消费结果
     */
    private boolean updateDispositionId(String data) {
        JSONObject jsonObject = JSON.parseObject(data);
        Integer id = jsonObject.getInteger("id");
        String dispositionId = jsonObject.getString("dispositionId");

        //根据任务ID查询
        AyStructureDisposition structureDisposition = dispositionService.getById(id);
        structureDisposition.setDispositionId(dispositionId);
        structureDisposition.setDefenseStatus(1);
        structureDisposition.setEndTime(null);
        structureDisposition.setBeginTime(LocalDateTime.now());
        //修改状态并存入缓存和redis
        AyDispositionPlanDto planDto= BeanCopyUtils.copy(structureDisposition,AyDispositionPlanDto.class);
        planDto.setEndTime(null);
        planDto.setBeginTime(null);
        planDto.setDeviceId(structureDisposition.getDispositionRangeDevice());
        if(structureDisposition.getDispositionType().equals(StruDispositionTypeEnum.TEXT.getValue())){
            planDto.setAlarmTypeId(AlarmTypeConstants.CONDITION_ALARM_CONTROL);
        }
        else if(structureDisposition.getDispositionType().equals(StruDispositionTypeEnum.IMAGE)){
            planDto.setAlarmTypeId(AlarmTypeConstants.IMAGE_ALARM_CONTROL);
        }
        planDto.setTaskName(structureDisposition.getName());
        RedisUtil.set(AyCacheConstants.CONTROL_STRUCTURE_CONDITION + dispositionId, JSON.toJSONString(planDto));

        //更新布控任务ID 及布防状态
        return dispositionService.getBaseMapper().update(null, new LambdaUpdateWrapper<AyStructureDisposition>().set(AyStructureDisposition::getDispositionId, dispositionId).set(AyStructureDisposition::getUpdatedBy, "SYSTEM").set(AyStructureDisposition::getDefenseStatus, 1).set(AyStructureDisposition::getBeginTime,LocalDateTime.now()).set(AyStructureDisposition::getEndTime,null)
                .eq(AyStructureDisposition::getId, id)) == 1;
    }

    /**
     * 任务创建失败时更新状态
     *
     * @param data 任务信息
     * @return 消费结果
     */
    private boolean taskUnusual(String data) {
        JSONObject jsonObject = JSON.parseObject(data);
        Integer id = jsonObject.getInteger("id");
        String msg = jsonObject.getString("msg");
        AyStructureTaskSon taskSon = taskSonService.getById(id);
        if (taskSon != null) {
            //更新子任务为异常
            LambdaUpdateWrapper<AyStructureTaskSon> wrapper = new LambdaUpdateWrapper<AyStructureTaskSon>().set(AyStructureTaskSon::getStatus, TaskStatusEnum.UNUSUAL.getValue()).set(AyStructureTaskSon::getUpdatedBy, "SYSTEM").set(AyStructureTaskSon::getErrorReason, msg)
                    .eq(AyStructureTaskSon::getId, taskSon.getId()).eq(AyStructureTaskSon::getStatus, TaskStatusEnum.CREATED.getValue()).eq(AyStructureTaskSon::getIsDeleted, DeleteStatusEnum.NOT_DELETED.getValue());

            boolean updateSonRes = taskSonService.update(null, wrapper);
            if (updateSonRes) {
                //更新主任务为异常
                LambdaUpdateWrapper<AyStructureTask> wrapper1 = Wrappers.lambdaUpdate();
                wrapper1.eq(AyStructureTask::getId, taskSon.getStructureTaskId());
                wrapper1.eq(AyStructureTask::getStatus, TaskStatusEnum.CREATED.getValue());
                wrapper1.eq(AyStructureTask::getIsDeleted, DeleteStatusEnum.NOT_DELETED.getValue());

                wrapper1.set(AyStructureTask::getStatus, TaskStatusEnum.UNUSUAL.getValue());
                wrapper1.set(AyStructureTask::getErrorReason, msg);
                wrapper1.set(AyStructureTask::getUpdatedBy, "SYSTEM");
                taskService.getBaseMapper().update(null, wrapper1);
            }
            return updateSonRes;

        } else {
            return false;
        }
    }


    /**
     * 布控任务创建失败时更新状态
     *
     * @param data 任务信息
     * @return 消费结果
     */
    private boolean dispositionUnusual(String data) {
        JSONObject jsonObject = JSON.parseObject(data);
        Integer id = jsonObject.getInteger("id");
        String msg = jsonObject.getString("msg");
        AyStructureDisposition structureDisposition = dispositionService.getById(id);
        if (structureDisposition != null) {
            //更新子任务为异常
            LambdaUpdateWrapper<AyStructureDisposition> wrapper = new LambdaUpdateWrapper<AyStructureDisposition>().set(AyStructureDisposition::getStatus, ControlStatusEnum.UNUSUAL.getValue()).set(AyStructureDisposition::getUpdatedBy, "SYSTEM").set(AyStructureDisposition::getDefenseStatus, 0)
                    .eq(AyStructureDisposition::getId, structureDisposition.getId()).eq(AyStructureDisposition::getStatus, ControlStatusEnum.RUNING.getValue()).eq(AyStructureDisposition::getIsDeleted, DeleteStatusEnum.NOT_DELETED.getValue());
            return dispositionService.update(null, wrapper);
        } else {
            return false;
        }
    }
}
